//------------------------------------------------------------------------------
// X2D Game Engine
// Copyright (C) 2006-2007 Janusz Kowalski
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#include "x2d_gameMode.h"
#include "x2d_main.h"
#include "imgSDL.h"
#include "mainLoop.h"
#include "x2d_New.h"
#include "global.h"
#include "x2tk_Container.h"
#include "x2tk.h"
#include "pmsg.h"

namespace x2d {

class Game : public x2tk::Container {
  private:
    Map *map_;
    GameView *view_;
    World *world_;
    // Player entity. Player is a special entity that has some functions to
    // control it.
    PlayerEnt *playerEnt_;
    Uint32 nextTime_;
  public:
    Game(int x, int y, int w, int h) : x2tk::Container(x,y,w,h) {
      map_ = new x2d::Map(64, 64);
      // !! Temporary.
      map_->load(X2D_PATH_MAPS "default.map");
      world_ = new World(map_);
      // !! Temporary.
      world_->load("/tmp/test.map");
      view_ = new x2d::GameView(0,32,getScreenWidget()->getW(),getScreenWidget()->getH()-64, world_);
      add(view_);
      nextTime_ = SDL_GetTicks();
      playerEnt_ = new PlayerEnt(world_);
      view_->setPlEnt(playerEnt_);
      // !! Temporary.
      new SomethingBadEnt(world_);
      new PhyEnt(world_);
      new PhyEnt(world_);
      new PhyEnt(world_);
      new PhyEnt(world_);
      new PhyEnt(world_);
      new PhyEnt(world_);
      new PhyEnt(world_);
      new PhyEnt(world_);
    }
    
    virtual ~Game() {
      delete playerEnt_;
      // Widget when deleted is also removed from it's parent
      delete view_;
      delete world_;
      delete map_;
    }
    
    virtual void timed(int id) {
      Uint32 currentTime = SDL_GetTicks();
      while(nextTime_ <= currentTime) {
         // Here we add 10 ms (because we want physics system to work at 100Hz)
        nextTime_ += 10;
        // We call the world's time callback.
        world_->timeCb();
        // We tell the view to follow player.
        double tx = playerEnt_->getX() + playerEnt_->getVelX()*32;
        double ty = playerEnt_->getY() + playerEnt_->getVelY()*32;
        view_->lookAt((int)tx, (int)ty);
        view_->move();
      }
    }
};

static Game *game;

void gameModeStart() {
  game = new Game(0,0,getScreenWidget()->getW(),getScreenWidget()->getH());
  getScreenWidget()->add(game);
  callRepetitively(game,0);
}

void gameModeEnd() {
  pmsgDebugF("Game %p is going down\n", game);
  delete game;
}

} // namespace x2d
